package queue

import (
	"errors"
	"sync"
)

//SimpleQ : 定义简单队列结构
type SimpleQ struct {
	front    *Node
	rear     *Node
	length   int
	capacity int
	mu       sync.Mutex
}

//NewSimpleQ : 创建简单队列对象
//use linked List data struct
func NewSimpleQ(cap int) (*SimpleQ, error) {
	if cap <= 0 {
		return nil, errors.New("capacity is less than 0")
	}

	front := &Node{
		value:    nil,
		previous: nil,
	}

	rear := &Node{
		value:    nil,
		previous: front,
		next:     nil,
	}

	front.next = rear

	return &SimpleQ{
		front:    front,
		rear:     rear,
		length:   0, //初始化长度
		capacity: cap,
		// mu:       new(sync.Mutex),
	}, nil
}

//Length :队列长度
func (s *SimpleQ) Length() int {
	return s.length
}

//Capacity :队列容量
func (s *SimpleQ) Capacity() int {
	return s.capacity
}

//Front : 头节点
func (s *SimpleQ) Front() *Node {
	if s.length == 0 {
		return nil
	}

	return s.front.next

}

//Rear ：尾部节点
func (s *SimpleQ) Rear() *Node {
	if s.length == 0 {
		return nil
	}

	return s.rear.previous
}

//Enqueue : 入队列
func (s *SimpleQ) Enqueue(value interface{}) bool {
	s.mu.Lock() //入队并发的处理
	defer s.mu.Unlock()
	if s.length == s.capacity || value == nil {
		return false
	}

	node := &Node{
		value: value,
	}

	//入队列以rear为参照物,注意赋值顺序
	node.previous = s.rear.previous
	node.next = s.rear
	s.rear.previous.next = node
	s.rear.previous = node
	s.length++
	return true
}

//Dequeue : 出队列
func (s *SimpleQ) Dequeue() interface{} {
	s.mu.Lock() //出队并发的处理
	defer s.mu.Unlock()
	// fmt.Println("len:", s.length)
	if s.length == 0 {
		return nil
	}
	//出队列以front为参照物
	node := s.front.next
	s.front.next = node.next
	//取出node置空前后指针
	node.next = nil
	node.previous = nil
	s.length--

	if s.length == 0 { //需要重新初始化MQ
		front := &Node{
			value:    nil,
			previous: nil,
		}

		rear := &Node{
			value:    nil,
			previous: front,
			next:     nil,
		}

		front.next = rear

		s.front = front
		s.rear = rear
		s.length = 0
		s.capacity = 100000
	}
	return node.value
}
